package control

import (
	"jvm/nzpJvm/instructions/base"
	"jvm/nzpJvm/runtime_area"
)
// 直接根据索引值在索引表中跳转。只有switch语句可以被编译成一个索引表时，才会出现tableswitch指令
type TABLE_SWITCH struct {
	defaultOffset int32
	low           int32
	high          int32
	jumpOffsets   []int32
}

func (self *TABLE_SWITCH) FetchOperands(reader *base.BytecodeReader) {
	// tableswitch指令之后的0——3个字节是填充字节，用来保证tableswitch指令和当前方法的第一条指令的偏移量是4的倍数
	reader.SkipPadding()
	self.defaultOffset = reader.ReadInt32()
	self.low = reader.ReadInt32()
	self.high = reader.ReadInt32()
	jumpOffsetsCount := self.high - self.low + 1
	self.jumpOffsets = reader.ReadInt32s(jumpOffsetsCount)

}
func (self *TABLE_SWITCH) Execute(frame *runtime_area.Frame) {
	index := frame.OperandStack().PopInt()

	var offset int
	if index >= self.low && index <= self.high {
		// 根据索引值直接跳转。
		offset = int(self.jumpOffsets[index-self.low])
	} else {
		offset = int(self.defaultOffset)
	}
	base.Branch(frame, offset)
}
